package com.financial.business.yspay.service.impl;

import com.financial.business.yspay.connector.SysconfigFeign;
import com.financial.business.yspay.connector.YsBusinessFeign;
import com.financial.business.yspay.constants.FinancialPayYsEnumConstants;
import com.financial.business.yspay.dao.FinancialPayYsDao;
import com.financial.business.yspay.domain.FinancialPayYsDO;
import com.financial.business.yspay.dto.YsAliPayDTO;
import com.financial.business.yspay.dto.YsWeChatPayDTO;
import com.financial.business.yspay.service.FinancialPayYsService;
import com.financial.business.yspay.utils.DateUtils;
import com.financial.business.yspay.utils.JsonUtils;
import com.financial.business.yspay.utils.ValidateUtils;
import com.financial.business.yspay.utils.apiresult.ApiResult;
import org.apache.commons.lang3.StringUtils;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.stereotype.Service;

import java.math.BigDecimal;
import java.math.RoundingMode;
import java.util.Date;
import java.util.HashMap;
import java.util.List;
import java.util.Map;


@Service
public class FinancialPayYsServiceImpl implements FinancialPayYsService {
    public static final Logger logger = LoggerFactory.getLogger(FinancialPayYsServiceImpl.class);

    @Autowired
    private FinancialPayYsDao financialPayYsDao;

    @Autowired
    private SysconfigFeign sysconfigFeign;

    @Autowired
    private YsBusinessFeign ysBusinessFeign;

    @Override
    public FinancialPayYsDO get(Integer id) {
        return financialPayYsDao.get(id);
    }

    @Override
    public List<FinancialPayYsDO> list(Map<String, Object> map) {
        return financialPayYsDao.list(map);
    }

    @Override
    public int count(Map<String, Object> map) {
        return financialPayYsDao.count(map);
    }

    @Override
    public int save(FinancialPayYsDO financialPayYs) {
        return financialPayYsDao.save(financialPayYs);
    }

    @Override
    public int update(FinancialPayYsDO financialPayYs) {
        return financialPayYsDao.update(financialPayYs);
    }

    /**
     * 银盛微信支付
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult ysWeChatPay(String requestParam) {
        YsWeChatPayDTO ysWeChatPayDTO = JsonUtils.convertBean(requestParam, YsWeChatPayDTO.class);
        Map<String, Object> mapParams = JsonUtils.jsonToMap(requestParam);
        /*支付金额*/
        Object tempParam = mapParams.get("total_amount");
        String totalAmount = tempParam == null ? null : tempParam.toString();
        /*三方支付专用的交易单号*/
        tempParam = mapParams.get("out_trade_no");
        String outTradeNo = tempParam == null ? null : tempParam.toString();
        /*商品的标题*/
        tempParam = mapParams.get("subject");
        String subject = tempParam == null ? null : tempParam.toString();
        /*微信用户所关注商家公众号的*/
        tempParam = mapParams.get("sub_openid");
        String subOpenid = tempParam == null ? null : tempParam.toString();
        /*支付类型*/
        tempParam = mapParams.get("pay_type");
        String payType = tempParam == null ? null : tempParam.toString();
        /*对接平台商户号*/
        tempParam = mapParams.get("store_no");
        String storeNo = tempParam == null ? null : tempParam.toString();
        /*平台支付单号*/
        tempParam = mapParams.get("pay_id");
        String payId = tempParam == null ? null : tempParam.toString();
        /*支付通道费用*/
        tempParam = mapParams.get("pay_fee");
        String payFee = tempParam == null ? null : tempParam.toString();
        /*回执地址*/
        tempParam = mapParams.get("notify_url");
        String notifyUrl = tempParam == null ? null : tempParam.toString();
        /*对接平台编码*/
        tempParam = mapParams.get("platform_no");
        String platformNo = tempParam == null ? null : tempParam.toString();
        if (StringUtils.isBlank(totalAmount) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(subject) || StringUtils.isBlank(payType)
                || StringUtils.isBlank(subOpenid) || StringUtils.isBlank(storeNo)
                || StringUtils.isBlank(payId) || StringUtils.isBlank(payFee)
                || StringUtils.isBlank(notifyUrl) || StringUtils.isBlank(platformNo)) {
            /*对所传字段进行非空校验判断*/
            return ApiResult.failure(ValidateUtils.validateProperty(ysWeChatPayDTO));
        }
        ApiResult apiResult = null;
        try {
            /*参数落库初始化*/
            FinancialPayYsDO payYsDO = new FinancialPayYsDO();
            logger.info("FinancialPayYsServiceImpl.ysWeChatPay()-----通过feign接口查询银盛微信支付业务配置参数");
            String ysBusinessPay = sysconfigFeign.getBusinessYsPayWechat();
            logger.info("FinancialPayYsServiceImpl.ysWeChatPay()-----通过feign接口查询银盛微信支付业务配置参数为:" + ysBusinessPay);
            if (StringUtils.isNotEmpty(ysBusinessPay)) {
                Map<String, Object> ysBusinessPayMap = JsonUtils.jsonToMap(ysBusinessPay);
                Object businessYsPay = ysBusinessPayMap.get("PARTNER_ID");
                String partnerId = businessYsPay == null ? null : businessYsPay.toString();
                businessYsPay = ysBusinessPayMap.get("APP_ID");
                String appId = businessYsPay == null ? null : businessYsPay.toString();
                businessYsPay = ysBusinessPayMap.get("SELLER_NAME");
                String sellerName = businessYsPay == null ? null : businessYsPay.toString();
                businessYsPay = ysBusinessPayMap.get("TIMEOUT_EXPRESS");
                String timeOutExpress = businessYsPay == null ? null : businessYsPay.toString();
                businessYsPay = ysBusinessPayMap.get("BUSINESS_CODE");
                String businessCode = businessYsPay == null ? null : businessYsPay.toString();
                /*组装银盛参数biz_content的json参数信息*/
                Map<String, Object> bizContentMap = new HashMap<String, Object>();
                bizContentMap.put("out_trade_no", outTradeNo);
                bizContentMap.put("shopdate", DateUtils.formatDate("yyyyMMdd"));
                bizContentMap.put("subject", subject);
                bizContentMap.put("total_amount", totalAmount);
                bizContentMap.put("seller_id", partnerId);
                bizContentMap.put("seller_name", sellerName);
                bizContentMap.put("timeout_express", timeOutExpress);
                bizContentMap.put("business_code", businessCode);
                bizContentMap.put("sub_openid", subOpenid);
                bizContentMap.put("appid", appId);
                /*将map转换为json调用调用银盛支付服务*/
                String bizContent = JsonUtils.toJSon(bizContentMap);
                /*封装支付渠道*/
                Map<String, Object> payMessage = new HashMap<>();
                payMessage.put("biz_content", bizContent);
                payMessage.put("pay_type", payType);
                String payMessageJson = JsonUtils.toJSon(payMessage);
                logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------拼接请求银盛数据格式：ysPayReceiptJson：" + payMessageJson);
                BigDecimal totalAmountDec = new BigDecimal(totalAmount).setScale(2, RoundingMode.HALF_UP);
                /*通过订单号查询库数据信息*/
                FinancialPayYsDO financialPayYsDOInfo = financialPayYsDao.getOne(outTradeNo);
                logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息,订单号:{}", financialPayYsDOInfo);
                int res = 0;
                if (financialPayYsDOInfo != null) {
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息存在,执行更新操作");
                    Map<String,Object> dataParams=new HashMap<>();
                    dataParams.put("outTradeNo",outTradeNo);
                    dataParams.put("gmtModified",new Date());
                    dataParams.put("returnMessage",FinancialPayYsEnumConstants.ENUM_RETURN_MESSAGE);
                    dataParams.put("state",FinancialPayYsEnumConstants.ENUM_STATE_WAIT);
                    BigDecimal totalAmountData = financialPayYsDOInfo.getTotalAmount();
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询银盛支付订单信息为,订单号为:{},支付金额为:{}", outTradeNo, totalAmountData);
                    String state = financialPayYsDOInfo.getState();
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询银盛支付订单信息为,订单号为:{},订单状态为:{}", outTradeNo, state);
                    if (totalAmountData.compareTo(totalAmountDec) != 0) {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付金额与当前支付金额不符");
                        return ApiResult.failure("历史订单信息支付金额与当前支付金额不符");
                    }
                    if (state.equals("2")) {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付状态为支付成功");
                        return ApiResult.success("该订单历史支付状态成功");
                    } else {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付状态为支付不成功或者为发起支付");
                        res = financialPayYsDao.updateInfo(dataParams);
                    }
                } else {
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息存在,执行创建操作");
                    payYsDO.setOutTradeNo(outTradeNo);
                    payYsDO.setPayId(payId);
                    payYsDO.setState(FinancialPayYsEnumConstants.ENUM_STATE_WAIT);
                    payYsDO.setPayFee(new BigDecimal(payFee));
                    payYsDO.setPayType(payType);
                    payYsDO.setReturnMessage(FinancialPayYsEnumConstants.ENUM_RETURN_MESSAGE);
                    payYsDO.setTotalAmount(new BigDecimal(totalAmount));
                    payYsDO.setStoreNo(storeNo);
                    payYsDO.setResqContent(requestParam);
                    payYsDO.setIsDelete(FinancialPayYsEnumConstants.ENUM_ISDELETE_UNDEL);
                    payYsDO.setGmtCreate(new Date());
                    payYsDO.setPlatformNo(platformNo);
                    res = financialPayYsDao.save(payYsDO);
                }
                if (res > 0) {
                    apiResult = ysBusinessFeign.ysPay(payMessageJson);
                    logger.info("payReturnApi信息为:{}", apiResult);
                    /*根据返回信息进行状态判断*/
                    Integer payCode = apiResult.getCode();
                    String apiResultMsg = apiResult.getResult().toString();
                    Map<String, Object> condMap = new HashMap<>();
                    condMap.put("outTradeNo", outTradeNo);
                    condMap.put("returnMessage", apiResultMsg);
                    if (payCode == FinancialPayYsEnumConstants.ENUM_RETURN_CODE && (apiResultMsg != null && apiResultMsg != "")) {
                        /*成功状态*/
                        condMap.put("state", FinancialPayYsEnumConstants.ENUM_STATE_SUC);
                        int updateInfoState = financialPayYsDao.updateInfo(condMap);
                        if (updateInfoState > 0) {
                            return ApiResult.success(apiResultMsg);
                        } else {
                            return ApiResult.failure(apiResult);
                        }
                    } else {
                        condMap.put("state", FinancialPayYsEnumConstants.ENUM_STATE_FAIL);
                        financialPayYsDao.updateInfo(condMap);
                        return ApiResult.success(apiResult);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("FinancialPayYsServiceImpl.ysWeChatPay()-----微信支付失败！对应的平台支付单号是：" + payId + "  对应的第三方支付单号为：" + outTradeNo);
        }
        return apiResult;
    }

    /**
     * 银盛支付宝支付
     *
     * @param requestParam
     * @return
     */
    @Override
    public ApiResult ysAliPay(String requestParam) {
        YsAliPayDTO ysAliPayDTO = (YsAliPayDTO) JsonUtils.convertBean(requestParam, YsAliPayDTO.class);
        Map<String, Object> mapParams = JsonUtils.jsonToMap(requestParam);
        Object tempParams = mapParams.get("total_amount");
        /*支付金额*/
        String totalAmount = tempParams == null ? null : tempParams.toString();
        /*三方支付专用交易单号*/
        tempParams = mapParams.get("out_trade_no");
        String outTradeNo = tempParams == null ? null : tempParams.toString();
        /*商品标题*/
        tempParams = mapParams.get("subject");
        String subject = tempParams == null ? null : tempParams.toString();
        /*支付宝用户ID*/
        tempParams = mapParams.get("buyer_id");
        String buyerId = tempParams == null ? null : tempParams.toString();
        /*支付类型*/
        tempParams = mapParams.get("pay_type");
        String payType = tempParams == null ? null : tempParams.toString();
        /*对接平台商户号*/
        tempParams = mapParams.get("store_no");
        String storeNo = tempParams == null ? null : tempParams.toString();
        /*平台支付单号*/
        tempParams = mapParams.get("pay_id");
        String payId = tempParams == null ? null : tempParams.toString();
        /*支付通道费用*/
        tempParams = mapParams.get("pay_fee");
        String payFee = tempParams == null ? null : tempParams.toString();
        /*回执地址*/
        tempParams = mapParams.get("notify_url");
        String notifyUrl = tempParams == null ? null : tempParams.toString();
        /*业务类型*/
        tempParams = mapParams.get("business_type");
        String businessType = tempParams == null ? null : tempParams.toString();
        /*对接平台编码*/
        tempParams = mapParams.get("platform_no");
        String platformNo = tempParams == null ? null : tempParams.toString();
        if (StringUtils.isBlank(totalAmount) || StringUtils.isBlank(outTradeNo)
                || StringUtils.isBlank(subject) || StringUtils.isBlank(buyerId)
                || StringUtils.isBlank(payType) || StringUtils.isBlank(storeNo)
                || StringUtils.isBlank(payId) || StringUtils.isBlank(payFee)
                || StringUtils.isBlank(notifyUrl) || StringUtils.isBlank(businessType)
                || StringUtils.isBlank(platformNo)) {
            return ApiResult.failure(ValidateUtils.validateProperty(ysAliPayDTO));
        }
        ApiResult apiResult = null;
        try {
            /*参数落库初始化*/
            FinancialPayYsDO payYsDO = new FinancialPayYsDO();
            /*拼接请求银盛参数包括配置业务参数信息*/
            logger.info("FinancialPayYsServiceImpl.ysAliPay()-----通过feign接口查询银盛支付宝支付业务配置参数");
            String ysBusinessPay = sysconfigFeign.getBusinessYsPayAliPay();
            logger.info("FinancialPayYsServiceImpl.ysAliPay()-----通过feign接口查询银盛支付宝支付业务配置参数为:" + ysBusinessPay);
            if (StringUtils.isNoneEmpty(ysBusinessPay)) {
                Map<String, Object> ysBusinessPayMap = JsonUtils.jsonToMap(ysBusinessPay);
                Object tempYsPay = ysBusinessPayMap.get("SELLER_ID");
                String sellerId = tempYsPay == null ? null : tempYsPay.toString();
                tempYsPay = ysBusinessPayMap.get("SELLER_NAME");
                String sellerName = tempYsPay == null ? null : tempYsPay.toString();
                tempYsPay = ysBusinessPayMap.get("TIMEOUT_EXPRESS");
                String timeOutExpress = tempYsPay == null ? null : tempYsPay.toString();
                tempYsPay = ysBusinessPayMap.get("BUSINESS_CODE");
                String businessCode = tempYsPay == null ? null : tempYsPay.toString();
                /*组装银盛参数的biz_content的json参数信息*/
                Map<String, Object> bizContentMap = new HashMap<>();
                bizContentMap.put("out_trade_no", outTradeNo);
                bizContentMap.put("shopdate", DateUtils.formatDate("yyyyMMdd"));
                bizContentMap.put("subject", subject);
                bizContentMap.put("total_amount", totalAmount);
                bizContentMap.put("seller_id", sellerId);
                bizContentMap.put("seller_name", sellerName);
                bizContentMap.put("timeout_express", timeOutExpress);
                bizContentMap.put("business_code", businessCode);
                bizContentMap.put("buyer_id", buyerId);
                /*将map转换为json调用调用银盛支付服务*/
                String bizContent = JsonUtils.toJSon(bizContentMap);
                /*封装支付渠道*/
                Map<String, Object> payMessage = new HashMap<>();
                payMessage.put("biz_content", bizContent);
                payMessage.put("pay_type", payType);
                String payMessageJson = JsonUtils.toJSon(payMessage);
                logger.info("FinancialPayYsServiceImpl.ysAliPay()------拼接请求银盛数据格式：ysPayReceiptJson：" + payMessageJson);
                BigDecimal totalAmountDec = new BigDecimal(totalAmount).setScale(2, RoundingMode.HALF_UP);
                /*通过订单号查询库数据信息*/
                FinancialPayYsDO financialPayYsDOInfo = financialPayYsDao.getOne(outTradeNo);
                logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息,订单号:{}", financialPayYsDOInfo);
                int res = 0;
                if (financialPayYsDOInfo != null) {
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息存在,执行更新操作");
                    Map<String,Object> dataParams=new HashMap<>();
                    dataParams.put("outTradeNo",outTradeNo);
                    dataParams.put("gmtModified",new Date());
                    dataParams.put("returnMessage",FinancialPayYsEnumConstants.ENUM_RETURN_MESSAGE);
                    dataParams.put("state",FinancialPayYsEnumConstants.ENUM_STATE_WAIT);
                    BigDecimal totalAmountData = financialPayYsDOInfo.getTotalAmount();
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询银盛支付订单信息为,订单号为:{},支付金额为:{}", outTradeNo, totalAmountData);
                    String state = financialPayYsDOInfo.getState();
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询银盛支付订单信息为,订单号为:{},订单状态为:{}", outTradeNo, state);
                    if (totalAmountData.compareTo(totalAmountDec) != 0) {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付金额与当前支付金额不符");
                        return ApiResult.failure("历史订单信息支付金额与当前支付金额不符");
                    }
                    if (state.equals("2")) {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付状态为支付成功");
                        return ApiResult.success("该订单历史支付状态成功");
                    } else {
                        logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------历史订单信息支付状态为支付不成功或者为发起支付");
                        res = financialPayYsDao.updateInfo(dataParams);
                    }
                } else {
                    logger.info("FinancialPayYsServiceImpl.ysWeChatPay()------通过订单号查询库数据信息存在,执行创建操作");
                    payYsDO.setOutTradeNo(outTradeNo);
                    payYsDO.setPayType(payType);
                    payYsDO.setPayId(payId);
                    payYsDO.setStoreNo(storeNo);
                    payYsDO.setPayFee(new BigDecimal(payFee));
                    payYsDO.setTotalAmount(new BigDecimal(totalAmount));
                    payYsDO.setGmtCreate(new Date());
                    payYsDO.setIsDelete(FinancialPayYsEnumConstants.ENUM_ISDELETE_UNDEL);
                    payYsDO.setResqContent(requestParam);
                    payYsDO.setReturnMessage(FinancialPayYsEnumConstants.ENUM_RETURN_MESSAGE);
                    payYsDO.setState(FinancialPayYsEnumConstants.ENUM_STATE_WAIT);
                    payYsDO.setPlatformNo(platformNo);
                    res = financialPayYsDao.save(payYsDO);
                }
                if (res > 0) {
                    apiResult = ysBusinessFeign.ysPay(payMessageJson);
                    /*根据返回信息进行状态判断*/
                    Integer payCode = apiResult.getCode();
                    String apiResultMsg = apiResult.getResult().toString();
                    Map<String, Object> condMap = new HashMap<>();
                    condMap.put("outTradeNo", outTradeNo);
                    condMap.put("returnMessage", apiResultMsg);
                    if (payCode == FinancialPayYsEnumConstants.ENUM_RETURN_CODE && (apiResultMsg != null && apiResultMsg != "")) {
                        /*成功状态*/
                        condMap.put("state", FinancialPayYsEnumConstants.ENUM_STATE_SUC);
                        int updateInfoState = financialPayYsDao.updateInfo(condMap);
                        if (updateInfoState > 0) {
                            return ApiResult.success(apiResultMsg);
                        } else {
                            return ApiResult.failure(apiResult);
                        }
                    } else {
                        condMap.put("state", FinancialPayYsEnumConstants.ENUM_STATE_FAIL);
                        financialPayYsDao.updateInfo(condMap);
                        return ApiResult.success(apiResult);
                    }
                }
            }
        } catch (Exception e) {
            e.printStackTrace();
            logger.error("FinancialPayYsServiceImpl.ysAliPay()-----支付宝支付失败！对应的平台支付单号是：" + payId + "  对应的第三方支付单号为：" + outTradeNo);
        }
        return apiResult;
    }

    /**
     * 通过map查询请求内容
     *
     * @param condMap
     * @return
     */
    @Override
    public String query(Map<String, Object> condMap) {

        return financialPayYsDao.query(condMap);
    }
}
